home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 July: Mac OS SDK / Dev.CD Jul 00 SDK2.toast / Development Kits / Cross Platform / QuickTime 4.1.2 Windows SDK / CIncludes / PEFBinaryFormat.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-12  |  50.1 KB  |  1,130 lines  |  [TEXT/R*ch]

  1. /*
  2.      File:        PEFBinaryFormat.h
  3.  
  4.      Contains:    PEF Types and Macros
  5.  
  6.      Version:    Technology:    Master Interfaces
  7.                  Release:    QuickTime 4.1
  8.  
  9.      Copyright:    (c) 1993-1996, 1998-1999 by Apple Computer, Inc., all rights reserved.
  10.  
  11.      Bugs?:        For bug reports, consult the following page on
  12.                  the World Wide Web:
  13.  
  14.                      http://developer.apple.com/bugreporter/
  15.  
  16. */
  17.  
  18.  
  19. #ifndef __PEFBINARYFORMAT__
  20. #define __PEFBINARYFORMAT__
  21.  
  22. #ifndef __MACTYPES__
  23.     #include <MacTypes.h>
  24. #endif
  25.  
  26.  
  27.  
  28.  
  29. #if PRAGMA_ONCE
  30. #pragma once
  31. #endif
  32.  
  33. #ifdef __cplusplus
  34. extern "C" {
  35. #endif
  36.  
  37. #if PRAGMA_IMPORT
  38. #pragma import on
  39. #endif
  40.  
  41. #if PRAGMA_STRUCT_ALIGN
  42.     #pragma options align=mac68k
  43. #elif PRAGMA_STRUCT_PACKPUSH
  44.     #pragma pack(push, 2)
  45. #elif PRAGMA_STRUCT_PACK
  46.     #pragma pack(2)
  47. #endif
  48.  
  49.  
  50.  
  51. /* -------------------------------------------------------------------------------------------- */
  52. /* Almost all types are padded for natural alignment.  However the PEFExportedSymbol type is    */
  53. /* 10 bytes long, containing two 32 bit fields and one 16 bit field.  Arrays of it must be        */
  54. /* packed, so it requires "68K" alignment.  Setting this globally to 68K should also help        */
  55. /* ensure consistent treatment across compilers.                                                */
  56.  
  57.  
  58.  
  59. /* ======================================================================================== */
  60. /* Overall Structure */
  61. /* ================= */
  62.  
  63.  
  64.  
  65. /* -------------------------------------------------------------------------------------------- */
  66. /* This header contains a complete set of types and macros for dealing with the PEF executable    */
  67. /* format.  While some description is provided, this header is not meant as a primary source    */
  68. /* of documentation on PEF.  An excellent specification of PEF can be found in the Macintosh    */
  69. /* Runtime Architectures book.  This header is primarily a physical format description.  Thus    */
  70. /* it depends on as few other headers as possible and structure fields have obvious sizes.        */
  71. /*                                                                                                 */
  72. /* The physical storage for a PEF executable is known as a "container".  This refers to just    */
  73. /* the executable itself, not the file etc.  E.g. if five DLLs are packaged in a single file's    */
  74. /* data fork, that one data fork has five containers within it.                                    */
  75. /*                                                                                                 */
  76. /* A PEF container consists of an overall header, followed by one or more section headers,        */
  77. /* followed by the section name table, followed by the contents for the sections.  Some kinds    */
  78. /* of sections have specific internal representation.  The "loader" section is the most common    */
  79. /* of these special sections.  It contains information on the exports, imports, and runtime        */
  80. /* relocations required to prepare the executable.  PEF containers are self contained, all        */
  81. /* portions are located via relative offsets.                                                    */
  82. /*                                                                                                 */
  83. /*                                                                                                 */
  84. /*            +-------------------------------+                                                    */
  85. /*            |        Container Header        |    40 bytes                                        */
  86. /*            +-------------------------------+                                                    */
  87. /*            |        Section 0 header        |    28 bytes each                                    */
  88. /*            |...............................|                                                    */
  89. /*            |            - - - -                |                                                    */
  90. /*            |...............................|                                                    */
  91. /*            |        Section n-1 header        |                                                    */
  92. /*            +-------------------------------+                                                    */
  93. /*            |        Section Name Table        |                                                    */
  94. /*            +-------------------------------+                                                    */
  95. /*            |        Section x raw data        |                                                    */
  96. /*            +-------------------------------+                                                    */
  97. /*             |            - - - -                |                                                    */
  98. /*            +-------------------------------+                                                    */
  99. /*            |        Section y raw data        |                                                    */
  100. /*            +-------------------------------+                                                    */
  101. /*                                                                                                 */
  102. /*                                                                                                 */
  103. /* The sections are implicitly numbered from 0 to n according to the order of their headers.    */
  104. /* The headers of the instantiated sections must precede those of the non-instantiated            */
  105. /* sections.  The ordering of the raw data is independent of the section header ordering.        */
  106. /* Each section header contains the offset for that section's raw data.                            */
  107.  
  108.  
  109.  
  110. /* =========================================================================================== */
  111. /* Container Header */
  112. /* ================ */
  113.  
  114.  
  115.  
  116.  
  117. struct PEFContainerHeader {
  118.     OSType                             tag1;                        /* Must contain 'Joy!'.*/
  119.     OSType                             tag2;                        /* Must contain 'peff'.  (Yes, with two 'f's.)*/
  120.     OSType                             architecture;                /* The ISA for code sections.  Constants in CodeFragments.h.*/
  121.     UInt32                             formatVersion;                /* The physical format version.*/
  122.     UInt32                             dateTimeStamp;                /* Macintosh format creation/modification stamp.*/
  123.     UInt32                             oldDefVersion;                /* Old definition version number for the code fragment.*/
  124.     UInt32                             oldImpVersion;                /* Old implementation version number for the code fragment.*/
  125.     UInt32                             currentVersion;                /* Current version number for the code fragment.*/
  126.     UInt16                             sectionCount;                /* Total number of section headers that follow.*/
  127.     UInt16                             instSectionCount;            /* Number of instantiated sections.*/
  128.     UInt32                             reservedA;                    /* Reserved, must be written as zero.*/
  129. };
  130. typedef struct PEFContainerHeader        PEFContainerHeader;
  131. enum {
  132.     kPEFTag1                    = FOUR_CHAR_CODE('Joy!'),        /* For non-Apple compilers: 0x4A6F7921.*/
  133.     kPEFTag2                    = FOUR_CHAR_CODE('peff'),        /* For non-Apple compilers: 0x70656666.*/
  134.     kPEFVersion                    = 0x00000001
  135. };
  136.  
  137.  
  138. enum {
  139.     kPEFFirstSectionHeaderOffset = sizeof(PEFContainerHeader)
  140. };
  141.  
  142. #define PEFFirstSectionNameOffset(container)    \
  143.             ( kPEFFirstSectionHeaderOffset + ((container)->sectionCount * sizeof ( PEFSectionHeader )) )
  144.  
  145.  
  146.  
  147. /* =========================================================================================== */
  148. /* Section Headers */
  149. /* =============== */
  150.  
  151.  
  152.  
  153.  
  154. struct PEFSectionHeader {
  155.     SInt32                             nameOffset;                    /* Offset of name within the section name table, -1 => none.*/
  156.     UInt32                             defaultAddress;                /* Default address, affects relocations.*/
  157.     UInt32                             totalLength;                /* Fully expanded size in bytes of the section contents.*/
  158.     UInt32                             unpackedLength;                /* Size in bytes of the "initialized" part of the contents.*/
  159.     UInt32                             containerLength;            /* Size in bytes of the raw data in the container.*/
  160.     UInt32                             containerOffset;            /* Offset of section's raw data.*/
  161.     UInt8                             sectionKind;                /* Kind of section contents/usage.*/
  162.     UInt8                             shareKind;                    /* Sharing level, if a writeable section.*/
  163.     UInt8                             alignment;                    /* Preferred alignment, expressed as log 2.*/
  164.     UInt8                             reservedA;                    /* Reserved, must be zero.*/
  165. };
  166. typedef struct PEFSectionHeader            PEFSectionHeader;
  167. enum {
  168.                                                                 /* Values for the sectionKind field.*/
  169.                                                                 /*    Section kind values for instantiated sections.*/
  170.     kPEFCodeSection                = 0,                            /* Code, presumed pure & position independent.*/
  171.     kPEFUnpackedDataSection        = 1,                            /* Unpacked writeable data.*/
  172.     kPEFPackedDataSection        = 2,                            /* Packed writeable data.*/
  173.     kPEFConstantSection            = 3,                            /* Read-only data.*/
  174.     kPEFExecDataSection            = 6,                            /* Intermixed code and writeable data.*/
  175.                                                                 /* Section kind values for non-instantiated sections.*/
  176.     kPEFLoaderSection            = 4,                            /* Loader tables.*/
  177.     kPEFDebugSection            = 5,                            /* Reserved for future use.*/
  178.     kPEFExceptionSection        = 7,                            /* Reserved for future use.*/
  179.     kPEFTracebackSection        = 8                                /* Reserved for future use.*/
  180. };
  181.  
  182.  
  183. enum {
  184.                                                                 /* Values for the shareKind field.*/
  185.     kPEFProcessShare            = 1,                            /* Shared within a single process.*/
  186.     kPEFGlobalShare                = 4,                            /* Shared across the entire system.*/
  187.     kPEFProtectedShare            = 5                                /* Readable across the entire system, writeable only to privileged code.*/
  188. };
  189.  
  190.  
  191.  
  192.  
  193. /* =========================================================================================== */
  194. /* Packed Data Contents */
  195. /* ==================== */
  196.  
  197.  
  198.  
  199. /* -------------------------------------------------------------------------------------------- */
  200. /* The raw contents of a packed data section are a sequence of byte codes.  The basic format    */
  201. /* has a 3 bit opcode followed by a 5 bit count.  Additional bytes might be used to contain        */
  202. /* counts larger than 31, and to contain a second or third count.  Further additional bytes        */
  203. /* contain actual data values to transfer.                                                        */
  204. /*                                                                                                 */
  205. /* All counts are represented in a variable length manner.  A zero in the initial 5 bit count    */
  206. /* indicates the actual value follows.  In this case, and for the second and third counts, the    */
  207. /* count is represented as a variable length sequence of bytes.  The bytes are stored in big    */
  208. /* endian manner, most significant part first.  The high order bit is set in all but the last    */
  209. /* byte.  The value is accumulated by shifting the current value up 7 bits and adding in the    */
  210. /* low order 7 bits of the next byte.                                                            */
  211.  
  212.  
  213. enum {
  214.                                                                 /* The packed data opcodes.*/
  215.     kPEFPkDataZero                = 0,                            /* Zero fill "count" bytes.*/
  216.     kPEFPkDataBlock                = 1,                            /* Block copy "count" bytes.*/
  217.     kPEFPkDataRepeat            = 2,                            /* Repeat "count" bytes "count2"+1 times.*/
  218.     kPEFPkDataRepeatBlock        = 3,                            /* Interleaved repeated and unique data.*/
  219.     kPEFPkDataRepeatZero        = 4                                /* Interleaved zero and unique data.*/
  220. };
  221.  
  222.  
  223. enum {
  224.     kPEFPkDataOpcodeShift        = 5,
  225.     kPEFPkDataCount5Mask        = 0x1F,
  226.     kPEFPkDataMaxCount5            = 31,
  227.     kPEFPkDataVCountShift        = 7,
  228.     kPEFPkDataVCountMask        = 0x7F,
  229.     kPEFPkDataVCountEndMask        = 0x80
  230. };
  231.  
  232.  
  233. #define PEFPkDataOpcode(byte) ( ((UInt8)(byte)) >> kPEFPkDataOpcodeShift )
  234.  
  235. #define PEFPkDataCount5(byte) ( ((UInt8)(byte)) & kPEFPkDataCount5Mask )
  236.  
  237. #define PEFPkDataComposeInstr(opcode,count5)        \
  238.             ( (((UInt8)(opcode)) << kPEFPkDataOpcodeShift) | ((UInt8)(count5)) )
  239.  
  240.  
  241.  
  242. /* -------------------------------------------------------------------------------------------- */
  243. /* The following code snippet can be used to input a variable length count.                        */
  244. /*                                                                                                 */
  245. /*        count = 0;                                                                                */
  246. /*        do {                                                                                    */
  247. /*            byte = *bytePtr++;                                                                    */
  248. /*            count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);            */
  249. /*        } while ( (byte & kPEFPkDataVCountEndMask) != 0 );                                        */
  250. /*                                                                                                 */
  251. /* The following code snippet can be used to output a variable length count to a byte array.    */
  252. /* This is more complex than the input code because the chunks are output in big endian order.    */
  253. /* Think about handling values like 0 or 0x030000.                                                */
  254. /*                                                                                                 */
  255. /*        count = 1;.                                                                                */
  256. /*        tempValue = value >> kPEFPkDataCountShift;                                                */
  257. /*        while ( tempValue != 0 ) {                                                                */
  258. /*            count += 1;                                                                            */
  259. /*            tempValue = tempValue >> kPEFPkDataCountShift;                                        */
  260. /*        }                                                                                        */
  261. /*                                                                                                 */
  262. /*        bytePtr += count;                                                                        */
  263. /*        tempPtr = bytePtr - 1;                                                                    */
  264. /*        *tempPtr-- = value;        // ! No need to mask, only the low order byte is stored.        */
  265. /*        for ( count -= 1; count != 0; count -= 1 ) {                                            */
  266. /*            value = value >> kPEFPkDataCountShift;                                                */
  267. /*            *tempPtr-- = value | kPEFPkDataCountEndMask;                                        */
  268. /*        }                                                                                        */
  269.  
  270.  
  271.  
  272. /* =========================================================================================== */
  273. /* Loader Section */
  274. /* ============== */
  275.  
  276.  
  277.  
  278. /* -------------------------------------------------------------------------------------------- */
  279. /* The loader section contains information needed to prepare the code fragment for execution.    */
  280. /* This includes this fragment's exports, the import libraries and the imported symbols from    */
  281. /* each library, and the relocations for the writeable sections.                                */
  282. /*                                                                                                 */
  283. /*            +-----------------------------------+                <-- containerOffset --------+    */
  284. /*            |        Loader Info Header            |    56 bytes                                |    */
  285. /*            |-----------------------------------|                                            |    */
  286. /*            |        Imported Library 0            |    24 bytes each                            |    */
  287. /*            |...................................|                                            |    */
  288. /*            |            - - -                    |                                            |    */
  289. /*            |...................................|                                            |    */
  290. /*            |        Imported Library l-1        |                                            |    */
  291. /*            |-----------------------------------|                                            |    */
  292. /*            |        Imported Symbol 0            |    4 bytes each                            |    */
  293. /*            |...................................|                                            |    */
  294. /*            |            - - -                    |                                            |    */
  295. /*            |...................................|                                            |    */
  296. /*            |         Imported Symbol i-1            |                                            |    */
  297. /*            |-----------------------------------|                                            |    */
  298. /*            |        Relocation Header 0            |    12 bytes each                            |    */
  299. /*            |...................................|                                            |    */
  300. /*            |            - - -                    |                                            |    */
  301. /*            |...................................|                                            |    */
  302. /*            |        Relocation Header r-1        |                                            |    */
  303. /*            |-----------------------------------|                <-- + relocInstrOffset -----|    */
  304. /*            |        Relocation Instructions        |                                            |    */
  305. /*            |-----------------------------------|                <-- + loaderStringsOffset --|    */
  306. /*            |        Loader String Table            |                                            |    */
  307. /*            |-----------------------------------|                <-- + exportHashOffset -----+    */
  308. /*            |        Export Hash Slot 0            |    4 bytes each                                */
  309. /*            |...................................|                                                */
  310. /*            |            - - -                    |                                                */
  311. /*            |...................................|                                                */
  312. /*            |         Export Hash Slot h-1        |                                                */
  313. /*            |-----------------------------------|                                                */
  314. /*            |        Export Symbol Key 0            |    4 bytes each                                */
  315. /*            |...................................|                                                */
  316. /*            |            - - -                    |                                                */
  317. /*            |...................................|                                                */
  318. /*            |        Export Symbol Key e-1        |                                                */
  319. /*            |-----------------------------------|                                                */
  320. /*            |        Export Symbol 0                |    10 bytes each                                */
  321. /*            |...................................|                                                */
  322. /*            |            - - -                    |                                                */
  323. /*            |...................................|                                                */
  324. /*            |        Export Symbol e-1            |                                                */
  325. /*            +-----------------------------------+                                                */
  326.  
  327.  
  328.  
  329.  
  330. struct PEFLoaderInfoHeader {
  331.     SInt32                             mainSection;                /* Section containing the main symbol, -1 => none.*/
  332.     UInt32                             mainOffset;                    /* Offset of main symbol.*/
  333.     SInt32                             initSection;                /* Section containing the init routine's TVector, -1 => none.*/
  334.     UInt32                             initOffset;                    /* Offset of the init routine's TVector.*/
  335.     SInt32                             termSection;                /* Section containing the term routine's TVector, -1 => none.*/
  336.     UInt32                             termOffset;                    /* Offset of the term routine's TVector.*/
  337.     UInt32                             importedLibraryCount;        /* Number of imported libraries.  ('l')*/
  338.     UInt32                             totalImportedSymbolCount;    /* Total number of imported symbols.  ('i')*/
  339.     UInt32                             relocSectionCount;            /* Number of sections with relocations.  ('r')*/
  340.     UInt32                             relocInstrOffset;            /* Offset of the relocation instructions.*/
  341.     UInt32                             loaderStringsOffset;        /* Offset of the loader string table.*/
  342.     UInt32                             exportHashOffset;            /* Offset of the export hash table.*/
  343.     UInt32                             exportHashTablePower;        /* Export hash table size as log 2.  (Log2('h'))*/
  344.     UInt32                             exportedSymbolCount;        /* Number of exported symbols.  ('e')*/
  345. };
  346. typedef struct PEFLoaderInfoHeader        PEFLoaderInfoHeader;
  347.  
  348.  
  349. /* =========================================================================================== */
  350. /* Imported Libraries */
  351. /* ------------------ */
  352.  
  353.  
  354.  
  355. struct PEFImportedLibrary {
  356.     UInt32                             nameOffset;                    /* Loader string table offset of library's name.*/
  357.     UInt32                             oldImpVersion;                /* Oldest compatible implementation version.*/
  358.     UInt32                             currentVersion;                /* Current version at build time.*/
  359.     UInt32                             importedSymbolCount;        /* Imported symbol count for this library.*/
  360.     UInt32                             firstImportedSymbol;        /* Index of first imported symbol from this library.*/
  361.     UInt8                             options;                    /* Option bits for this library.*/
  362.     UInt8                             reservedA;                    /* Reserved, must be zero.*/
  363.     UInt16                             reservedB;                    /* Reserved, must be zero.*/
  364. };
  365. typedef struct PEFImportedLibrary        PEFImportedLibrary;
  366. enum {
  367.                                                                 /* Bits for the PEFImportedLibrary options field.*/
  368.     kPEFWeakImportLibMask        = 0x40,                            /* The imported library is allowed to be missing.*/
  369.     kPEFInitLibBeforeMask        = 0x80                            /* The imported library must be initialized first.*/
  370. };
  371.  
  372.  
  373.  
  374.  
  375. /* =========================================================================================== */
  376. /* Imported Symbols */
  377. /* ---------------- */
  378.  
  379.  
  380.  
  381. /* -------------------------------------------------------------------------------------------- */
  382. /* The PEFImportedSymbol type has the following bit field layout.                                */
  383. /*                                                                                                 */
  384. /*                                                                       3                        */
  385. /*         0             7 8                                             1                        */
  386. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  387. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  388. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  389. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  390.  
  391.  
  392.  
  393.  
  394. struct PEFImportedSymbol {
  395.     UInt32                             classAndName;
  396. };
  397. typedef struct PEFImportedSymbol        PEFImportedSymbol;
  398. enum {
  399.     kPEFImpSymClassShift        = 24,
  400.     kPEFImpSymNameOffsetMask    = 0x00FFFFFF,
  401.     kPEFImpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215*/
  402. };
  403.  
  404. #define PEFImportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFImpSymClassShift))
  405. #define PEFImportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFImpSymNameOffsetMask)
  406.  
  407. #define PEFComposeImportedSymbol(class,nameOffset)        \
  408.             ( ( ((UInt32)(class)) << kPEFImpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  409.  
  410. enum {
  411.                                                                 /* Imported and exported symbol classes.*/
  412.     kPEFCodeSymbol                = 0x00,
  413.     kPEFDataSymbol                = 0x01,
  414.     kPEFTVectorSymbol            = 0x02,
  415.     kPEFTOCSymbol                = 0x03,
  416.     kPEFGlueSymbol                = 0x04,
  417.     kPEFUndefinedSymbol            = 0x0F,
  418.     kPEFWeakImportSymMask        = 0x80
  419. };
  420.  
  421.  
  422.  
  423.  
  424. /* =========================================================================================== */
  425. /* Exported Symbol Hash Table */
  426. /* -------------------------- */
  427.  
  428.  
  429.  
  430. /* -------------------------------------------------------------------------------------------- */
  431. /* Exported symbols are described in four parts, optimized for speed of lookup.  These parts    */
  432. /* are the "export hash table", the "export key table", the "export symbol table", and the        */
  433. /* "export name table".  Overall they contain a flattened representation of a fairly normal        */
  434. /* hashed symbol table.                                                                            */
  435. /*                                                                                                */
  436. /* The export hash table is an array of small fixed size elements.  The number of elements is    */
  437. /* a power of 2.  A 32 bit hash word for a symbol is converted into an index into this array.    */
  438. /* Each hash slot contains a count of the number of exported symbols that map to this slot and    */
  439. /* the index of the first of those symbols in the key and symbol tables.  Of course some hash    */
  440. /* slots will have a zero count.                                                                */
  441. /*                                                                                                */
  442. /* The key and symbol tables are also arrays of fixed size elements, one for each exported        */
  443. /* symbol.  Their entries are grouped by hash slot, those elements mapping to the same hash        */
  444. /* slot are contiguous.  The key table contains just the full 32 bit hash word for each            */
  445. /* exported symbol.  The symbol table contains the offset of the symbol's name in the string    */
  446. /* table and other information about the exported symbol.                                        */
  447. /*                                                                                                */
  448. /* To look up an export you take the hashword and compute the hash slot index.  You then scan    */
  449. /* the indicated portion of the key table for matching hashwords.  If a hashword matches, you    */
  450. /* look at the corresponding symbol table entry to find the full symbol name.  If the names        */
  451. /* match the symbol is found.                                                                    */
  452.  
  453.  
  454.  
  455. /* -------------------------------------------------------------------------------------------- */
  456. /* The following function may be used to compute the hash table size.  Signed values are used    */
  457. /* just to avoid potential code generation overhead for unsigned division.                        */
  458. /*                                                                                                 */
  459. /*        UInt8    PEFComputeHashTableExponent    ( SInt32    exportCount )                            */
  460. /*        {                                                                                        */
  461. /*            SInt32    exponent;                                                                    */
  462. /*                                                                                                 */
  463. /*            const SInt32    kExponentLimit        = 16;    // Arbitrary, but must not exceed 30.    */
  464. /*            const SInt32    kAverageChainLimit    = 10;    // Arbitrary, for space/time tradeoff.    */
  465. /*                                                                                                 */
  466. /*            for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) {                    */
  467. /*                if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break;                */
  468. /*            }                                                                                    */
  469. /*                                                                                                 */
  470. /*            return exponent;                                                                    */
  471. /*                                                                                                 */
  472. /*        }    // PEFComputeHashTableExponent ()                                                    */
  473.  
  474.  
  475.  
  476. /* -------------------------------------------------------------------------------------------- */
  477. /* The PEFExportedSymbolHashSlot type has the following bit field layout.                        */
  478. /*                                                                                                 */
  479. /*                                   1 1                                 3                        */
  480. /*         0                         3 4                                 1                        */
  481. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  482. /*        | symbol count              | index of first export key         |                        */
  483. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  484. /*        |<-- 14 bits -------------->|<-- 18 bits ---------------------->|                        */
  485.  
  486.  
  487.  
  488.  
  489. struct PEFExportedSymbolHashSlot {
  490.     UInt32                             countAndStart;
  491. };
  492. typedef struct PEFExportedSymbolHashSlot PEFExportedSymbolHashSlot;
  493. enum {
  494.     kPEFHashSlotSymCountShift    = 18,
  495.     kPEFHashSlotFirstKeyMask    = 0x0003FFFF,
  496.     kPEFHashSlotMaxSymbolCount    = 0x00003FFF,                    /*  16,383*/
  497.     kPEFHashSlotMaxKeyIndex        = 0x0003FFFF                    /* 262,143*/
  498. };
  499.  
  500. #define PEFHashTableIndex(fullHashWord,hashTablePower)    \
  501.             ( ( (fullHashWord) ^ ((fullHashWord) >> (hashTablePower)) ) & ((1 << (hashTablePower)) - 1) )
  502.  
  503. #define PEFHashSlotSymbolCount(countAndStart)    ((UInt32) ((countAndStart) >> kPEFHashSlotSymCountShift))
  504. #define PEFHashSlotFirstKey(countAndStart)        ((countAndStart) & kPEFHashSlotFirstKeyMask)
  505.  
  506. #define PEFComposeExportedSymbolHashSlot(symbolCount,firstKey)    \
  507.             ( ( ((UInt32)(symbolCount)) << kPEFHashSlotSymCountShift ) | ( (UInt32)(firstKey) ) )
  508.  
  509.  
  510.  
  511. /* =========================================================================================== */
  512. /* Exported Symbol Hash Key */
  513. /* ------------------------ */
  514.  
  515.  
  516.  
  517.  
  518. struct PEFSplitHashWord {
  519.     UInt16                             nameLength;
  520.     UInt16                             hashValue;
  521. };
  522. typedef struct PEFSplitHashWord            PEFSplitHashWord;
  523.  
  524. struct PEFExportedSymbolKey {
  525.     union {
  526.         UInt32                             fullHashWord;
  527.         PEFSplitHashWord                 splitHashWord;
  528.     }                                 u;
  529. };
  530. typedef struct PEFExportedSymbolKey        PEFExportedSymbolKey;
  531. enum {
  532.     kPEFHashLengthShift            = 16,
  533.     kPEFHashValueMask            = 0x0000FFFF,
  534.     kPEFHashMaxLength            = 0x0000FFFF                    /* 65,535*/
  535. };
  536.  
  537. #define PEFHashNameLength(fullHashWord)    ((UInt32) ((fullHashWord) >> kPEFHashLengthShift))
  538. #define PEFHashValue(fullHashWord)    ((fullHashWord) & kPEFHashValueMask)
  539.  
  540. #define PEFComposeFullHashWord(nameLength,hashValue)    \
  541.             ( ( ((UInt32)(nameLength)) << kPEFHashLengthShift ) | ( (UInt32)(hashValue) ) )
  542.  
  543.  
  544.  
  545. /* ---------------------------------------------------------------------------------------------------- */
  546. /* The following function computes the full 32 bit hash word.                                            */
  547. /*                                                                                                         */
  548. /*        UInt32    PEFComputeHashWord    ( BytePtr    nameText,        // ! First "letter", not length byte.    */
  549. /*                                      UInt32    nameLength )    // ! The text may be zero terminated.    */
  550. /*        {                                                                                                */
  551. /*            BytePtr    charPtr        = nameText;                                                                */
  552. /*            SInt32    hashValue    = 0;        // ! Signed to match old published algorithm.                */
  553. /*            UInt32    length        = 0;                                                                    */
  554. /*            UInt32    limit;                                                                                */
  555. /*            UInt32    result;                                                                                */
  556. /*            UInt8    currChar;                                                                            */
  557. /*                                                                                                         */
  558. /*            #define PseudoRotate(x)  ( ( (x) << 1 ) - ( (x) >> 16 ) )                                    */
  559. /*                                                                                                         */
  560. /*            for ( limit = nameLength; limit > 0; limit -= 1 ) {                                            */
  561. /*                currChar = *charPtr++;                                                                    */
  562. /*                if ( currChar == NULL ) break;                                                            */
  563. /*                length += 1;                                                                            */
  564. /*                hashValue = PseudoRotate ( hashValue ) ^ currChar;                                        */
  565. /*            }                                                                                            */
  566. /*                                                                                                         */
  567. /*            result    = (length << kPEFHashLengthShift) |                                                    */
  568. /*                      ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask));                    */
  569. /*                                                                                                         */
  570. /*            return result;                                                                                */
  571. /*                                                                                                         */
  572. /*        }    // PEFComputeHashWord ()                                                                    */
  573.  
  574.  
  575.  
  576. /* =========================================================================================== */
  577. /* Exported Symbols */
  578. /* ---------------- */
  579.  
  580.  
  581.  
  582.  
  583. struct PEFExportedSymbol {                                        /* ! This structure is 10 bytes long and arrays are packed.*/
  584.     UInt32                             classAndName;                /* A combination of class and name offset.*/
  585.     UInt32                             symbolValue;                /* Typically the symbol's offset within a section.*/
  586.     SInt16                             sectionIndex;                /* The index of the section, or pseudo-section, for the symbol.*/
  587. };
  588. typedef struct PEFExportedSymbol        PEFExportedSymbol;
  589.  
  590. /* -------------------------------------------------------------------------------------------- */
  591. /* The classAndName field of the PEFExportedSymbol type has the following bit field layout.        */
  592. /*                                                                                                 */
  593. /*                                                                       3                        */
  594. /*         0             7 8                                             1                        */
  595. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  596. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  597. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  598. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  599.  
  600.  
  601. enum {
  602.     kPEFExpSymClassShift        = 24,
  603.     kPEFExpSymNameOffsetMask    = 0x00FFFFFF,
  604.     kPEFExpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215*/
  605. };
  606.  
  607. #define PEFExportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFExpSymClassShift))
  608. #define PEFExportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFExpSymNameOffsetMask)
  609.  
  610. #define PEFComposeExportedSymbol(class,nameOffset)        \
  611.             ( ( ((UInt32)(class)) << kPEFExpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  612.  
  613. enum {
  614.                                                                 /* Negative section indices indicate pseudo-sections.*/
  615.     kPEFAbsoluteExport            = -2,                            /* The symbol value is an absolute address.*/
  616.     kPEFReexportedImport        = -3                            /* The symbol value is the index of a reexported import.*/
  617. };
  618.  
  619.  
  620.  
  621.  
  622. /* =========================================================================================== */
  623. /* Loader Relocations */
  624. /* ================== */
  625.  
  626.  
  627.  
  628. /* -------------------------------------------------------------------------------------------- */
  629. /* The relocations for a section are defined by a sequence of instructions for an abstract        */
  630. /* machine that is specifically geared to performing relocations commonly needed for the "CFM"    */
  631. /* code generation model.  These instructions occur in 16 bit chunks.  Most instructions have    */
  632. /* just a single chunk.  Instructions that are larger than 16 bits have an opcode and some of    */
  633. /* the operands in the first chunk, with other operands in following chunks.                    */
  634. /*                                                                                                */
  635. /* ! Note that the multi-chunk relocations have separate "Compose" macros for each chunk.  The    */
  636. /* ! macros have the same basic name with a positional suffix of "_1st", "_2nd", etc.            */
  637.  
  638.  
  639.  
  640.  
  641. typedef UInt16                             PEFRelocChunk;
  642.  
  643. struct PEFLoaderRelocationHeader {
  644.     UInt16                             sectionIndex;                /* Index of the section to be fixed up.*/
  645.     UInt16                             reservedA;                    /* Reserved, must be zero.*/
  646.     UInt32                             relocCount;                    /* Number of 16 bit relocation chunks.*/
  647.     UInt32                             firstRelocOffset;            /* Offset of first relocation instruction.*/
  648. };
  649. typedef struct PEFLoaderRelocationHeader PEFLoaderRelocationHeader;
  650.  
  651. /* -------------------------------------------------------------------------------------------- */
  652. /* ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the        */
  653. /* ! total number of bytes of relocation instructions.  While most relocation instructions are    */
  654. /* ! 16 bits long, some are longer so the number of complete relocation instructions may be        */
  655. /* ! less than the relocCount value.                                                            */
  656.  
  657.  
  658.  
  659. /* ------------------------------------------------------------------------------------ */
  660. /* The PEFRelocField macro is a utility for extracting relocation instruction fields.    */
  661.  
  662.  
  663. #define PEFRFShift(offset,length)    (16 - ((offset) + (length)))
  664. #define PEFRFMask(length)            ((1 << (length)) - 1)
  665.  
  666. #define PEFRelocField(chunk,offset,length)    \
  667.             ( ( (chunk) >> (16 - ((offset) + (length))) ) & ((1 << (length)) - 1) )
  668.  
  669.  
  670.  
  671. /* =========================================================================================== */
  672. /* Basic Relocation Opcodes */
  673. /* ------------------------ */
  674.  
  675.  
  676. /* -------------------------------------------------------------------------------------------- */
  677. /* The number of opcode bits varies from 2 to 7.  The enumeration and switch table given here    */
  678. /* are defined in terms of the most significant 7 bits of the first instruction chunk.  An        */
  679. /* instruction is decoded by using the most significant 7 bits as an index into the opcode        */
  680. /* table, which in turn contains appropriately masked forms of the most significant 7 bits.        */
  681. /* The macro PEFRelocBasicOpcode assumes a declaration of the form.                                */
  682. /*                                                                                                 */
  683. /*        UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes };    */
  684.  
  685.  
  686. enum {
  687.     kPEFRelocBasicOpcodeRange    = 128
  688. };
  689.  
  690. #define PEFRelocBasicOpcode(firstChunk) (kPEFRelocBasicOpcodes[(firstChunk)>>9])
  691.  
  692.  
  693.  
  694. /* -------------------------------------------------------------------------------------------- */
  695. /* The relocation opcodes, clustered by major and minor groups.  The instructions within a        */
  696. /* cluster all have the same bit field layout.  The enumeration values use the high order 7        */
  697. /* bits of the relocation instruction.  Unused low order bits are set to zero.                    */
  698.  
  699. enum {
  700.     kPEFRelocBySectDWithSkip    = 0x00,                            /* Binary: 00x_xxxx*/
  701.     kPEFRelocBySectC            = 0x20,                            /* Binary: 010_0000, group is "RelocRun"*/
  702.     kPEFRelocBySectD            = 0x21,                            /* Binary: 010_0001*/
  703.     kPEFRelocTVector12            = 0x22,                            /* Binary: 010_0010*/
  704.     kPEFRelocTVector8            = 0x23,                            /* Binary: 010_0011*/
  705.     kPEFRelocVTable8            = 0x24,                            /* Binary: 010_0100*/
  706.     kPEFRelocImportRun            = 0x25,                            /* Binary: 010_0101*/
  707.     kPEFRelocSmByImport            = 0x30,                            /* Binary: 011_0000, group is "RelocSmIndex"*/
  708.     kPEFRelocSmSetSectC            = 0x31,                            /* Binary: 011_0001*/
  709.     kPEFRelocSmSetSectD            = 0x32,                            /* Binary: 011_0010*/
  710.     kPEFRelocSmBySection        = 0x33,                            /* Binary: 011_0011*/
  711.     kPEFRelocIncrPosition        = 0x40,                            /* Binary: 100_0xxx*/
  712.     kPEFRelocSmRepeat            = 0x48,                            /* Binary: 100_1xxx*/
  713.     kPEFRelocSetPosition        = 0x50,                            /* Binary: 101_000x*/
  714.     kPEFRelocLgByImport            = 0x52,                            /* Binary: 101_001x*/
  715.     kPEFRelocLgRepeat            = 0x58,                            /* Binary: 101_100x*/
  716.     kPEFRelocLgSetOrBySection    = 0x5A,                            /* Binary: 101_101x*/
  717.     kPEFRelocUndefinedOpcode    = 0xFF                            /* Used in masking table for all undefined values.*/
  718. };
  719.  
  720.  
  721.  
  722. /* ----------------------------------------------------------------------------    */
  723. /* The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode    */
  724. /* beyond the 7 used by the dispatch table.  To be precise it has 6 plus 4 but    */
  725. /* the dispatch table ignores the 7th bit, so the subdispatch is on all 4 extra    */
  726. /* subopcode bits.                                                                */
  727.  
  728. enum {
  729.     kPEFRelocLgBySectionSubopcode = 0x00,                        /* Binary: 0000*/
  730.     kPEFRelocLgSetSectCSubopcode = 0x01,                        /* Binary: 0001*/
  731.     kPEFRelocLgSetSectDSubopcode = 0x02                            /* Binary: 0010*/
  732. };
  733.  
  734. #define PEFRelocLgSetOrBySubopcode(chunk) (((chunk) >> 6) & 0x0F)
  735.  
  736.  
  737.  
  738. /* -------------------------------------------------------------------------------------------- */
  739. /* The initial values for the opcode "masking" table.  This has the enumeration values from        */
  740. /* above with appropriate replications for "don't care" bits.  It is almost certainly shorter    */
  741. /* and faster to look up the masked value in a table than to use a branch tree.                    */
  742.  
  743.  
  744. #define PEFMaskedBasicOpcodes                                                                                                                    \
  745.                                                                                                                                                 \
  746.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x00 .. 0x03 */    \
  747.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x04 .. 0x07 */    \
  748.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x08 .. 0x0B */    \
  749.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x0C .. 0x0F */    \
  750.                                                                                                                                                 \
  751.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x10 .. 0x13 */    \
  752.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x14 .. 0x17 */    \
  753.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x18 .. 0x1B */    \
  754.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x1C .. 0x1F */    \
  755.                                                                                                                                                 \
  756.             kPEFRelocBySectC,            kPEFRelocBySectD,            kPEFRelocTVector12,            kPEFRelocTVector8,            /* 0x20 .. 0x23 */    \
  757.             kPEFRelocVTable8,            kPEFRelocImportRun,            kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x24 .. 0x27 */    \
  758.                                                                                                                                                 \
  759.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x28 .. 0x2B */    \
  760.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x2C .. 0x2F */    \
  761.                                                                                                                                                 \
  762.             kPEFRelocSmByImport,        kPEFRelocSmSetSectC,        kPEFRelocSmSetSectD,        kPEFRelocSmBySection,        /* 0x30 .. 0x33 */    \
  763.                                                                                                                                                 \
  764.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x34 .. 0x37 */    \
  765.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x38 .. 0x3B */    \
  766.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x3C .. 0x3F */    \
  767.                                                                                                                                                 \
  768.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x40 .. 0x43 */    \
  769.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x44 .. 0x47 */    \
  770.                                                                                                                                                 \
  771.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x48 .. 0x4B */    \
  772.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x4C .. 0x4F */    \
  773.                                                                                                                                                 \
  774.             kPEFRelocSetPosition,        kPEFRelocSetPosition,        kPEFRelocLgByImport,        kPEFRelocLgByImport,        /* 0x50 .. 0x53 */    \
  775.                                                                                                                                                 \
  776.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x54 .. 0x57 */    \
  777.                                                                                                                                                 \
  778.             kPEFRelocLgRepeat,            kPEFRelocLgRepeat,            kPEFRelocLgSetOrBySection,    kPEFRelocLgSetOrBySection,    /* 0x58 .. 0x5B */    \
  779.                                                                                                                                                 \
  780.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x5C .. 0x5F */    \
  781.                                                                                                                                                 \
  782.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x60 .. 0x63 */    \
  783.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x64 .. 0x67 */    \
  784.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x68 .. 0x6B */    \
  785.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x6C .. 0x6F */    \
  786.                                                                                                                                                 \
  787.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x70 .. 0x73 */    \
  788.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x74 .. 0x77 */    \
  789.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x78 .. 0x7B */    \
  790.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode    /* 0x7C .. 0x7F */
  791.  
  792.  
  793.  
  794. /* =========================================================================================== */
  795. /* RelocBySectDWithSkip Instruction */
  796. /* -------------------------------- */
  797.  
  798.  
  799.  
  800. /* -------------------------------------------------------------------------------------------- */
  801. /* The "RelocBySectDWithSkip" instruction has the following bit field layout.                    */
  802. /*                                                                                                 */
  803. /*                             1         1                                                        */
  804. /*         0 1 2             9 0         5                                                        */
  805. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  806. /*        |0 0| skip count    | rel count |                                                        */
  807. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  808. /*        | 2 |<-- 8 bits --->|<--  6 --->|                                                        */
  809. /*                                                                                                 */
  810. /* ! Note that the stored skip count and reloc count are the actual values!                        */
  811.  
  812. enum {
  813.     kPEFRelocWithSkipMaxSkipCount = 255,
  814.     kPEFRelocWithSkipMaxRelocCount = 63
  815. };
  816.  
  817. #define PEFRelocWithSkipSkipCount(chunk)    PEFRelocField ( (chunk), 2, 8 )
  818. #define PEFRelocWithSkipRelocCount(chunk)    PEFRelocField ( (chunk), 10, 6 )
  819.  
  820. #define PEFRelocComposeWithSkip(skipCount,relocCount)    \
  821.             ( 0x0000 | (((UInt16)(skipCount)) << 6) | ((UInt16)(relocCount)) )
  822.  
  823.  
  824.  
  825. /* =========================================================================================== */
  826. /* RelocRun Group */
  827. /* -------------- */
  828.  
  829.  
  830.  
  831. /* -------------------------------------------------------------------------------------------- */
  832. /* The "RelocRun" group includes the "RelocBySectC", "RelocBySectD", "RelocTVector12",            */
  833. /* "RelocTVector8", "RelocVTable8", and "RelocImportRun" instructions.  This group has the        */
  834. /* following bit field layout.                                                                    */
  835. /*                                                                                                 */
  836. /*                                       1                                                        */
  837. /*         0   2 3     6 7               5                                                        */
  838. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  839. /*        |0 1 0| subop.| run length      |                                                        */
  840. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  841. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                        */
  842. /*                                                                                                 */
  843. /* ! Note that the stored run length is the actual value minus 1, but the macros deal with the    */
  844. /* ! actual value!                                                                                */
  845.  
  846. enum {
  847.     kPEFRelocRunMaxRunLength    = 512
  848. };
  849.  
  850. #define PEFRelocRunSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  851. #define PEFRelocRunRunLength(chunk)    (PEFRelocField ( (chunk), 7, 9 ) + 1)
  852.  
  853. #define PEFRelocComposeRun(subopcode,runLength)    \
  854.             ( 0x4000 | (((UInt16)(subopcode)) << 9) | ((UInt16)((runLength)-1)) )
  855.  
  856. #define PEFRelocComposeBySectC(runLength)        PEFRelocComposeRun ( 0, (runLength) )
  857. #define PEFRelocComposeBySectD(runLength)        PEFRelocComposeRun ( 1, (runLength) )
  858. #define PEFRelocComposeTVector12(runLength)        PEFRelocComposeRun ( 2, (runLength) )
  859. #define PEFRelocComposeTVector8(runLength)        PEFRelocComposeRun ( 3, (runLength) )
  860. #define PEFRelocComposeVTable8(runLength)        PEFRelocComposeRun ( 4, (runLength) )
  861. #define PEFRelocComposeImportRun(runLength)        PEFRelocComposeRun ( 5, (runLength) )
  862.  
  863.  
  864.  
  865. /* =========================================================================================== */
  866. /* RelocSmIndex Group */
  867. /* ------------------ */
  868.  
  869.  
  870.  
  871. /* ----------------------------------------------------------------------------------------    */
  872. /* The "RelocSmIndex" group includes the "RelocSmByImport", "RelocSmSetSectC",                */
  873. /* "RelocSmSetSectD" and "RelocSmBySection" instructions.  This group has the following bit    */
  874. /* field layout.                                                                            */
  875. /*                                                                                             */
  876. /*                                       1                                                    */
  877. /*         0   2 3     6 7               5                                                    */
  878. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  879. /*        |0 1 1| subop.| index           |                                                    */
  880. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  881. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                    */
  882. /*                                                                                             */
  883. /* ! Note that the stored index is the actual value!                                        */
  884.  
  885. enum {
  886.     kPEFRelocSmIndexMaxIndex    = 511
  887. };
  888.  
  889. #define PEFRelocSmIndexSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  890. #define PEFRelocSmIndexIndex(chunk)        PEFRelocField ( (chunk), 7, 9 )
  891.  
  892. #define PEFRelocComposeSmIndex(subopcode,index)    \
  893.             ( 0x6000 | (((UInt16)(subopcode)) << 9) | ((UInt16)(index)) )
  894.  
  895. #define PEFRelocComposeSmByImport(index)    PEFRelocComposeSmIndex ( 0, (index) )
  896. #define PEFRelocComposeSmSetSectC(index)    PEFRelocComposeSmIndex ( 1, (index) )
  897. #define PEFRelocComposeSmSetSectD(index)    PEFRelocComposeSmIndex ( 2, (index) )
  898. #define PEFRelocComposeSmBySection(index)    PEFRelocComposeSmIndex ( 3, (index) )
  899.  
  900.  
  901.  
  902. /* =========================================================================================== */
  903. /* RelocIncrPosition Instruction */
  904. /* ----------------------------- */
  905.  
  906.  
  907.  
  908. /* -------------------------------------------------------------------------------------------- */
  909. /* The "RelocIncrPosition" instruction has the following bit field layout.                        */
  910. /*                                                                                                 */
  911. /*                                       1                                                        */
  912. /*         0     3 4                     5                                                        */
  913. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  914. /*        |1 0 0 0| offset                |                                                        */
  915. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  916. /*        |<- 4 ->|<-- 12 bits ---------->|                                                        */
  917. /*                                                                                                 */
  918. /* ! Note that the stored offset is the actual value minus 1, but the macros deal with the        */
  919. /* ! actual value!                                                                                */
  920.  
  921. enum {
  922.     kPEFRelocIncrPositionMaxOffset = 4096
  923. };
  924.  
  925. #define PEFRelocIncrPositionOffset(chunk)    (PEFRelocField ( (chunk), 4, 12 ) + 1)
  926.  
  927. #define PEFRelocComposeIncrPosition(offset)    \
  928.             ( 0x8000 | ((UInt16)((offset)-1)) )
  929.  
  930.  
  931.  
  932. /* =========================================================================================== */
  933. /* RelocSmRepeat Instruction */
  934. /* ------------------------- */
  935.  
  936.  
  937.  
  938. /* -------------------------------------------------------------------------------------------- */
  939. /* The "RelocSmRepeat" instruction has the following bit field layout.                            */
  940. /*                                                                                                 */
  941. /*                                       1                                                        */
  942. /*         0     3 4     7 8             5                                                        */
  943. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  944. /*        |1 0 0 1| chnks | repeat count  |                                                        */
  945. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  946. /*        |<- 4 ->|<- 4 ->|<-- 8 bits --->|                                                        */
  947. /*                                                                                                 */
  948. /* ! Note that the stored chunk count and repeat count are the actual values minus 1, but the    */
  949. /* ! macros deal with the actual values!                                                        */
  950.  
  951. enum {
  952.     kPEFRelocSmRepeatMaxChunkCount = 16,
  953.     kPEFRelocSmRepeatMaxRepeatCount = 256
  954. };
  955.  
  956. #define PEFRelocSmRepeatChunkCount(chunk)    (PEFRelocField ( (chunk), 4, 4 ) + 1)
  957. #define PEFRelocSmRepeatRepeatCount(chunk)    (PEFRelocField ( (chunk), 8, 8 ) + 1)
  958.  
  959. #define PEFRelocComposeSmRepeat(chunkCount,repeatCount)    \
  960.             ( 0x9000 | ((((UInt16)(chunkCount))-1) << 8) | (((UInt16)(repeatCount))-1) )
  961.  
  962.  
  963.  
  964. /* =========================================================================================== */
  965. /* RelocSetPosition Instruction */
  966. /* ---------------------------- */
  967.  
  968.  
  969.  
  970. /* -------------------------------------------------------------------------------------------- */
  971. /* The "RelocSetPosition" instruction has the following bit field layout.                        */
  972. /*                                                                                                 */
  973. /*                                       1                                   1                    */
  974. /*         0         5 6                 5     0                             5                    */
  975. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  976. /*        |1 0 1 0 0 0| offset (high)     |   | offset (low)                  |                    */
  977. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  978. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  979. /*                                                                                                 */
  980. /* ! Note that the stored offset is the actual value!                                            */
  981.  
  982. enum {
  983.     kPEFRelocSetPosMaxOffset    = 0x03FFFFFF                    /* 67,108,863*/
  984. };
  985.  
  986. #define PEFRelocSetPosOffsetHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  987.  
  988. #define PEFRelocSetPosFullOffset(firstChunk,secondChunk)    \
  989.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  990.  
  991. #define PEFRelocComposeSetPosition_1st(fullOffset)    \
  992.             ( 0xA000 | ((UInt16) (((UInt32)(fullOffset)) >> 16) ) )
  993. #define PEFRelocComposeSetPosition_2nd(fullOffset)    \
  994.             ( (UInt16) ((UInt32)(fullOffset) & 0xFFFF) )
  995.  
  996.  
  997.  
  998. /* =========================================================================================== */
  999. /* RelocLgByImport Instruction */
  1000. /* --------------------------- */
  1001.  
  1002.  
  1003.  
  1004. /* -------------------------------------------------------------------------------------------- */
  1005. /* The "RelocLgByImport" instruction has the following bit field layout.                        */
  1006. /*                                                                                                 */
  1007. /*                                       1                                   1                    */
  1008. /*         0         5 6                 5     0                             5                    */
  1009. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1010. /*        |1 0 1 0 0 1| index (high)      |   | index (low)                   |                    */
  1011. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1012. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  1013. /*                                                                                                 */
  1014. /* ! Note that the stored offset is the actual value!                                            */
  1015.  
  1016. enum {
  1017.     kPEFRelocLgByImportMaxIndex    = 0x03FFFFFF                    /* 67,108,863*/
  1018. };
  1019.  
  1020. #define PEFRelocLgByImportIndexHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  1021.  
  1022. #define PEFRelocLgByImportFullIndex(firstChunk,secondChunk)    \
  1023.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  1024.  
  1025. #define PEFRelocComposeLgByImport_1st(fullIndex)    \
  1026.             ( 0xA400 | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  1027. #define PEFRelocComposeLgByImport_2nd(fullIndex)    \
  1028.             ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
  1029.  
  1030.  
  1031.  
  1032. /* =========================================================================================== */
  1033. /* RelocLgRepeat Instruction */
  1034. /* ------------------------- */
  1035.  
  1036.  
  1037.  
  1038. /* -------------------------------------------------------------------------------------------- */
  1039. /* The "RelocLgRepeat" instruction has the following bit field layout.                            */
  1040. /*                                                                                                 */
  1041. /*                             1         1                                   1                    */
  1042. /*         0         5 6     9 0         5     0                             5                    */
  1043. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1044. /*        |1 0 1 1 0 0| chnks | rpt (high)|   | repeat count (low)            |                    */
  1045. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1046. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  1047. /*                                                                                                 */
  1048. /* ! Note that the stored chunk count is the actual value minus 1, but the macros deal with        */
  1049. /* ! the actual value!  The stored repeat count is the actual value!                            */
  1050.  
  1051. enum {
  1052.     kPEFRelocLgRepeatMaxChunkCount = 16,
  1053.     kPEFRelocLgRepeatMaxRepeatCount = 0x003FFFFF                /* 4,194,303*/
  1054. };
  1055.  
  1056. #define PEFRelocLgRepeatChunkCount(chunk)        (PEFRelocField ( (chunk), 6, 4 ) + 1)
  1057. #define PEFRelocLgRepeatRepeatCountHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1058.  
  1059. #define PEFRelocLgRepeatFullRepeatCount(firstChunk,secondChunk)    \
  1060.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1061.  
  1062. #define PEFRelocComposeLgRepeat_1st(chunkCount,fullRepeatCount)    \
  1063.             ( 0xB000 | ((((UInt16)(chunkCount))-1) << 6) | ((UInt16) (((UInt32)(fullRepeatCount)) >>16 ) ) )
  1064. #define PEFRelocComposeLgRepeat_2nd(chunkCount,fullRepeatCount)    \
  1065.             ( (UInt16) ((UInt32)(fullRepeatCount) & 0xFFFF) )
  1066.  
  1067.  
  1068.  
  1069. /* =========================================================================================== */
  1070. /* RelocLgSetOrBySection Group */
  1071. /* --------------------------- */
  1072.  
  1073.  
  1074.  
  1075. /* -------------------------------------------------------------------------------------------- */
  1076. /* The "RelocLgSetOrBySection" instruction is really a group including the "RelocLgBySection",    */
  1077. /* "RelocLgSetSectC" and "RelocLgSetSectD" instructions.  This group has the following bit        */
  1078. /* field layout.                                                                                */
  1079. /*                                                                                                 */
  1080. /*                             1         1                                   1                    */
  1081. /*         0         5 6     9 0         5     0                             5                    */
  1082. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1083. /*        |1 0 1 1 0 1| subop | idx (high)|   | index (low)                   |                    */
  1084. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1085. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  1086. /*                                                                                                 */
  1087. /* ! Note that the stored index is the actual value!                                            */
  1088.  
  1089. enum {
  1090.     kPEFRelocLgSetOrBySectionMaxIndex = 0x003FFFFF                /* 4,194,303*/
  1091. };
  1092.  
  1093. #define PEFRelocLgSetOrBySectionSubopcode(chunk)    PEFRelocField ( (chunk), 6, 4 )
  1094. #define PEFRelocLgSetOrBySectionIndexHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1095.  
  1096. #define PEFRelocLgSetOrBySectionFullIndex(firstChunk,secondChunk)    \
  1097.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1098.  
  1099. #define PEFRelocComposeLgSetOrBySection_1st(subopcode,fullIndex)    \
  1100.             ( 0xB400 | (((UInt16)(subopcode)) << 6) | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  1101. #define PEFRelocComposeLgSetOrBySection_2nd(subopcode,fullIndex)    \
  1102.             ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
  1103.  
  1104. #define PEFRelocComposeLgBySection(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x00, (fullIndex) )
  1105. #define PEFRelocComposeLgSetSectC(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x01, (fullIndex) )
  1106. #define PEFRelocComposeLgSetSectD(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x02, (fullIndex) )
  1107.  
  1108.  
  1109.  
  1110. #if PRAGMA_STRUCT_ALIGN
  1111.     #pragma options align=reset
  1112. #elif PRAGMA_STRUCT_PACKPUSH
  1113.     #pragma pack(pop)
  1114. #elif PRAGMA_STRUCT_PACK
  1115.     #pragma pack()
  1116. #endif
  1117.  
  1118. #ifdef PRAGMA_IMPORT_OFF
  1119. #pragma import off
  1120. #elif PRAGMA_IMPORT
  1121. #pragma import reset
  1122. #endif
  1123.  
  1124. #ifdef __cplusplus
  1125. }
  1126. #endif
  1127.  
  1128. #endif /* __PEFBINARYFORMAT__ */
  1129.  
  1130.